/*
 *  Copyright 2008 Mark Ashworth <javameme@gmail.com>.
 * 
 *  Licensed under the GNU General Public License v3 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.gnu.org/licenses/gpl-3.0.html
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package xperiment.metaphor.model.entity;

import java.util.List;
import xperiment.metaphor.model.*;
import metaphor.service.ServiceException;
import metaphor.persistence.filter.Query;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import metaphor.persistence.filter.SimpleExpression;

/**
 * A person's role.
 * @author Mark Ashworth
 * @version 1.0.0
 * @since 1.0.0
 */
//@Entity
//@Table(name = "role")
public class Role extends DomainObject implements Persistent, Named, Comparable {
	
    /* The unique id of the role */
    //@Id @GeneratedValue(strategy=GenerationType.AUTO)
    //@Column(name = "role_id", unique = true, nullable = false)
    private Long id = null;
    
    /* The name of the role. */
    //@Column(name = "role_name", unique=true, nullable=false, length=25)
    private String name;
    
    /* The description of the role */
    //@Column(name = "description", nullable=true, length=1096)
    private String description;
    
    /* Whether the role is enabled */
    //@Column(name = "enabled", nullable = false)
    private boolean enabled = true;

	/**
	 * Default constructor
	 */
	public Role() {
        this(null);
	}
	
	/**
	 * Creates the named role
	 * @param name The name of the role
	 */
	public Role(String name) {
		super();
        this.name = name;
	}
	
    /**
	 * Creates the named role
	 * @param name The name of the role
     * @param description The description of the role
	 */
	public Role(String name, String description) {
		super();
        this.name = name;
        this.description = description;
	}
    
    /**
     * The unique id of the role
     * @return Long
     */
	public Long getId() {
		return this.id;
	}
	
    /**
     * The name of the role.
     * @return String
     */
	public String getName() {
		return this.name;
	}
    
    /**
     * The description of the role
     * @return String
     */
    
	public String getDescription() {
		return this.description;
	}

    
    /**
     * Whether the role is enabled
     * @return boolean
     */	
	public boolean isEnabled() {
		return enabled;
	}

    /**
     * Whether the roles is enabled
     * @param enabled The new value
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * Saves the role if not already present in the persistent store
     */
    public Role save() throws SaveException {

        /*
         * Persist the role
         */
        try {
            List values = getDao().retrieve(Query.forClass(Role.class).add(SimpleExpression.ilike("name", getName())));
            if (values != null && values.size() == 1) {
                Role r = (Role) values.get(0);
                this.id = r.getId();
            } else if (values != null && values.size() == 0) {
                Role r = (Role) getDao().persist(this);
                this.id = r.getId();
            } else if (values != null && values.size() > 1) {
                throw new SaveException("Multiple roles found for name " + getName());
            } else {
                throw new SaveException("Null values returned from retrieve query");
            }
            return this;
        } catch (ServiceException e) {
            throw new SaveException("Unable to save role", e);
        }
    }

    /**
     * Returns the role name as the String representation of the role
     * @return String
     */
    @Override
    public String toString() {
        return getName();
    }
    
    /**
     * Returns the XML representation of the role<br />
     * &lt;role class="xperiment.metaphor.model.user.Role" id="1" name="ROLE_ANONYMOUS" description="Anonymous" enabled="true" /&gt;
     * @return String
     */
    public String toXML() {
        return "<role class='" 
                + getClass().getName() 
                + "' id='" + getId()
                + "' name='" + getName()
                + "' description='" + getDescription()
                + "' enabled='" + isEnabled()
                + "' />";
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) { return false; }
        if (obj == this) { return true; }
        if (getClass() != obj.getClass()) { return false; }

        final Role rhs = (Role) obj;

        return new EqualsBuilder()
                .append(getName(), rhs.getName())
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 47).append(getName()).toHashCode();
    }

    @Override
    public int compareTo(Object o) {
        Role rhs = (Role) o;
        return new CompareToBuilder()
                .append(getName(), rhs.getName())
                .toComparison();
	}
}
